#!/usr/bin/python
# -*- coding:utf-8 -*-

import mcpack
import tornado.httpserver
import tornado.ioloop
import tornado.web
import tornado.autoreload
import sys
import logging

import socket
import struct
import json
import types


#自己扩展url指向的类，调用其对应方法post/get
class StsIndexHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("stsIndex.html")
    def post(self, *args, **kwargs):
        self.write("post request")


class NsheadTsheadMcpack:

    def __init__(self):
        pass

    def makeNsHead(self, length):
        nshead = {
            "id": 0,
            "verison": 1,
            "log_id": 1989,
            "provider": "zihua_send",
            "magic_num": 0xfb709394,
            "reserved": 0,
            "body_len": length,
        }
        header = []
        for i in ["id", "verison", "log_id", "provider", "magic_num", "reserved", "body_len"]:
            header.append(nshead[i])
        # format of header: 2*unsigned short + uint + string with size=16 +
        # 3*uint = 36 byte
        header_p = struct.pack("2HI16s3I", *header)
        return header_p

    def makeTsHead(self, tshead):
        # tshead = {
        # "cmd_no":100003, #UINT32
        # "err_no":0, #UINT32
        # "data_type":"titlekit", #char[64]
        # "page_no":0, #UINT32
        # "num_per_page":20, #UINT32
        # "ret_num":0,#UINT32
        # "disp_num":0, #UINT32
        # }
        header = []
        for i in ['cmd_no', 'err_no', 'data_type', 'page_no', 'num_per_page', 'ret_num', 'disp_num']:
            header.append(tshead[i])
        # format of header: 2*uint32 + 64*char + 4*uint32 = 8+64+16=88 byte
        header_p = struct.pack("2I64s4I", *header)
        return header_p

    def parseNsHead(self, header):
        return struct.unpack("2HI16s3I", header)

    def parseTsHead(self, header):
        return struct.unpack("2I64s4I", header)

    def recvMcpack(self, sk, total):
        data = ""
        length = total
        while length > 0:
            data += sk.recv(length)
            length = total - len(data)
        return data

    def recvAndParse(self, sk):
        try:
            nshead_data = sk.recv(36)
            nshead_header = self.parseNsHead(nshead_data)
        except:
            logging.error("recv header failed!")
            return False

        other_data = self.recvMcpack(sk, nshead_header[-1])
        tshead_header = other_data[0:88]
        mcpack_data = other_data[88:]

        res_dict = {}
        res_dict['nshead'] = nshead_header
        res_dict['tshead'] = self.parseTsHead(tshead_header)
        res_dict['mcpack'] = mcpack.loads(mcpack_data)
        return res_dict

    def sendNsHeadTsHeadMcpack(self, addr, tshead, data):
        sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sk.settimeout(5)
        try:
            sk.connect(addr)
        except Exception, e:
            logging.error("Cannot connect to EC@%s", addr)
            logging.error(e)
            res_dict = {}
            res_dict['error:'] = str(e)
            return res_dict

        pack = mcpack.dumps_version(mcpack.mcpackv1, data, buffer_size=10240)
        # pack = mcpack.dumps(data)
        tshead_header = self.makeTsHead(tshead)

        nshead_header = self.makeNsHead(len(tshead_header + pack))
        try:
            sk.sendall(nshead_header + tshead_header + pack)
        except Exception, e:
            logging.error(e)
            return False

        res_dict = self.recvAndParse(sk)
        sk.close()
        return res_dict

    def go(self, addr, tshead, send_mcpack):
        # d = {
        #     "word": mcpack.STR(send_mcpack['word']),
        #     "type": mcpack.INT32(send_mcpack['type']),
        #     "copycat": mcpack.INT32(send_mcpack['copycat']),
        #     "from": mcpack.INT32(send_mcpack['from']),
        #     "limit": mcpack.INT32(send_mcpack['limit']),
        #     "ip": mcpack.INT32(send_mcpack['ip']),
        #     "client_from": mcpack.INT32(send_mcpack['client_from']),
        #     "use_new_red_policy": mcpack.INT32(send_mcpack['use_new_red_policy']),
        #     "converge_array": mcpack.ARR(send_mcpack['converge_array']),
        #     "father_query": mcpack.STR(send_mcpack['father_query']),

        # }
        d = send_mcpack
        res_dict = self.sendNsHeadTsHeadMcpack(addr, tshead, d)
        return res_dict


#sts sug发送nshead + tshead + mcpack
class StsHandler(tornado.web.RequestHandler):
    def get(self, args=None):
        print 555555555
        type = self.get_argument('type', -1)
        query = self.get_argument('query', '')
        _from = self.get_argument('from', -1)
        if type == -1 or query == "" or _from == -1:
            self.write("param error   type  query  from is need!")
            return
        sts_ip = self.get_argument('stsip', '127.0.0.1')
        sts_port = 26880
        if self.request.arguments.has_key("stsport"):
            sts_port = self.get_argument('stsport')
        else:
            if int(type) == 5:  # 词图检索
                sts_port = 5618

        sts_addr = (sts_ip, int(sts_port))
        limit = self.get_argument('limit', 20)

        ntm = NsheadTsheadMcpack()
        count = 0
        tshead = {
            "cmd_no": 100003,  # UINT32
            "err_no": 0,  # UINT32
            "data_type": "titlekit",  # char[64]
            "page_no": 0,  # UINT32
            "num_per_page": int(limit),  # UINT32
            "ret_num": 0,  # UINT32
            "disp_num": 0,  # UINT32
        }

        #print type(query.encode('utf-8'))
        send_mcpack = {
            'word': query.encode('utf-8'),
            'type': int(type),
            'copycat': 0,
            'from': int(_from),
            'limit': 0,
            'ip': 1234567,
            'client_from': 0,
            'use_new_red_policy': 1,
            #"use_cluster" : 1,
            'converge_array': [
                {
                    "num_per_page": 10,
                    "type": 1,
                    "page_no": 0
                },
                {
                    "num_per_page": 5,
                    "type": 2,
                    "page_no": 0
                },
                {
                    "num_per_page": 5,
                    "type": 4,
                    "page_no": 0
                },
                {
                    "num_per_page": 15,
                    "type": 5,
                    "page_no": 0
                },
                {
                    "num_per_page": 3,
                    "type": 8,
                    "page_no": 0
                },
                {
                    "num_per_page": 4,
                    "type": 9,
                    "page_no": 0
                }
            ],
            'father_query': '',
        }
        print 1111111111
        res_dict = ntm.go(sts_addr, tshead, send_mcpack)
        print 1111111111222
        self.write(json.dumps(res_dict))
        print 11111111113333
